<template>
  <div style="margin-top:10px;box-shadow: rgb(0 0 0 / 10%) 0px 2px 12px 0px;">
    <Toolbar style="border-bottom: 1px solid #efefef" :editor="editorRef" :defaultConfig="toolbarConfig"
      mode="default" />
    <Editor style="height: calc(100vh - 280px); overflow-y: hidden;" v-model="valueHtml" :defaultConfig="editorConfig"
      mode="default" @onCreated="handleCreated" />
  </div>
</template>
<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { SlateElement } from '@wangeditor/editor'

import { onBeforeUnmount, ref, shallowRef, inject, defineExpose, watch, nextTick } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { postArticleImage, deleteArticleImages } from '@/utils/articleHttp'
import { ElMessage } from 'element-plus';

import { useRoute } from 'vue-router'
const route = useRoute()
// 插入图片成功后的回调
type ImageElement = SlateElement & {
  src: string
  alt: string
  url: string
  href: string
}
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
// 全局状态
const store: any = inject('store')
// 内容 HTML
const valueHtml = ref<string>('')
// 插入的图片
const InsertionImages: ImageElement[] = []
// 背景图片
const bg = ref<string>('')

// 传入的文本 默认值没有
const props = withDefaults(defineProps<{
  updateHtml: string
}>(), { updateHtml: '' })


route.query.id && watch(() => props.updateHtml, () => {
  valueHtml.value = props.updateHtml
  nextTick(() => {
    InsertionImages.push(...editorRef.value.getElemsByType('image'))
  })
}, {
  immediate: true // 上来就监视
})
// 上传图片
type InsertFnType = (url: string, alt: string, href: string) => void
const updatedImage = async (file: File, insertFn: InsertFnType) => {
  const fd = new FormData()
  fd.append('file', file)
  postArticleImage(fd).then(res => {
    if (res.data.ok) {
      insertFn(store.state.BaseUrl + res.data.imageUrl, '服务错误', '')
    }
    else ElMessage.error(res.data.info)
  })
}


const onInsertedImage = (imageNode: ImageElement | null) => {
  if (imageNode == null) return
  // 放入图片
  InsertionImages.push(imageNode)
}

const toolbarConfig = {
  excludeKeys: [
    'group-video']
}
const editorConfig = {
  placeholder: '请输入内容...',
  MENU_CONF: {
    // 配置上传图片
    uploadImage: {
      // 小于该值就插入 base64 格式（而不上传），默认为 0
      base64LimitSize: 10 * 1024, // 10kb
      customUpload: updatedImage
    },
    insertImage: {
      onInsertedImage: onInsertedImage
    }
  }
}


// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}
// 删除服务器 图片的方法
const deletImage = (): void => {
  // 最后的图片
  const images = (editorRef.value.getElemsByType('image') as ImageElement[]).map(item => item.src)
  const deletImages = InsertionImages.filter(item => !images.includes(item.src))
  //  调用删除的函数
  deleteArticleImages(deletImages.map(item => item.src))
  images[0] && (bg.value = images[0].split(':3999/')[1])
}

// 清空编辑器里的东西 
const clearHtml = () => {
  InsertionImages.splice(0)
}

// 把外面用的东西暴露了出去方便外面使用
defineExpose({ deletImage, valueHtml, bg, clearHtml, InsertionImages })
</script>

<style  lang="scss">
.w-e-bar-item {
  padding: 1px;
}
</style>